import com.vladsch.flexmark.ast.*;
import com.vladsch.flexmark.ext.tables.TablesExtension;
import com.vladsch.flexmark.ext.toc.TocExtension;
import com.vladsch.flexmark.html.HtmlRenderer;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.util.ast.Node;
import com.vladsch.flexmark.util.ast.NodeVisitor;
import com.vladsch.flexmark.util.ast.VisitHandler;
import com.vladsch.flexmark.util.collection.iteration.ReversiblePeekingIterator;
import com.vladsch.flexmark.util.data.MutableDataSet;
import com.vladsch.flexmark.util.misc.Extension;
import com.vladsch.flexmark.util.sequence.BasedSequence;
import org.jsoup.Jsoup;
import org.jsoup.helper.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.TextNode;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;


public class FlexMarkUtil {

    private static MutableDataSet options = new MutableDataSet();
    private static Parser parser;
    private static HtmlRenderer renderer;
    // 定义常见的 Markdown 节点类型
    private static final Set<Class<?>> MARKDOWN_NODES = new HashSet<>();

    static {
        options.set(Parser.EXTENSIONS, Arrays.<Extension>asList(TocExtension.create(), TablesExtension.create()));
        parser = Parser.builder(options).build();
        renderer = HtmlRenderer.builder(options).build();
        // 初始化常见的 Markdown 元素类型
        MARKDOWN_NODES.add(Heading.class);         // 标题
        MARKDOWN_NODES.add(BulletList.class);      // 无序列表
        MARKDOWN_NODES.add(OrderedList.class);     // 有序列表
        MARKDOWN_NODES.add(ListItem.class);        // 列表项
        MARKDOWN_NODES.add(Link.class);            // 链接
        MARKDOWN_NODES.add(Image.class);           // 图片
        MARKDOWN_NODES.add(FencedCodeBlock.class); // 代码块
        MARKDOWN_NODES.add(BlockQuote.class);
        MARKDOWN_NODES.add(Paragraph.class);
        MARKDOWN_NODES.add(StrongEmphasis.class);
    }


    /**
     * 修改 Markdown 文本中所有图片的 URL
     *
     * @param originalMarkdown 原始 Markdown 文本
     * @return 修改后的 Markdown 文本
     */
    public static String modifyImageUrlsAndHtmlContent(String originalMarkdown, Map<String, String> urlMap) {
        // 步骤1：解析原始 Markdown 为 AST
        Node document = parser.parse(originalMarkdown);
        // 步骤2：自定义 NodeVisitor，遍历并修改 Image 节点的 URL
        NodeVisitor visitor = new NodeVisitor(
                new VisitHandler<>(Image.class, imageNode -> {
                    // 获取原始图片 URL
                    String originalUrl = imageNode.getUrl().toString();
                    // 替换路径（仅替换包含旧前缀的路径）
                    if (urlMap.containsKey(originalUrl)) {
                        String newPath = urlMap.get(originalUrl);
                        imageNode.setUrl(BasedSequence.of(newPath));
                        //imageNode.setText(BasedSequence.of(newPath));
                    }
                }
                ),
                //如果是html代码块检测是否包含markdown内容，如果包含将markdown内容转为html替换htmlBlock的内容
                new VisitHandler<>(HtmlBlock.class, htmlBlock -> {
                    String html = htmlBlock.getChars().toString();
                    Document document1 = Jsoup.parse(html);
                    converHtml(document1, urlMap);
                    String document1String = document1.body().html();
                    com.vladsch.flexmark.util.ast.Document newDoucument = parser.parse(document1String);
                    if (getNodeContentLine(newDoucument.getFirstChild()) != null) {
                        htmlBlock.setContentLines(getNodeContentLine(newDoucument.getFirstChild()));
                    }
                })
        );
        // 步骤3：执行遍历（触发 URL 修改）
        visitor.visit(document);
        String rendered = renderer.render(document);
        // 步骤4：将修改后的 AST 转换回 Markdown 文本
        return document.getBaseSequence().toString();
    }

    public static List<BasedSequence> getNodeContentLine(Node node) {
        if (node instanceof HtmlBlock) {
            HtmlBlock htmlNode = (HtmlBlock) node;
            return htmlNode.getContentLines();
        }
        return null;
    }

    public static void converHtml(org.jsoup.nodes.Node document, Map<String, String> pngUrlMap) {
        if (document == null || document.childNodeSize() <= 0) {
            return;
        }
        for (org.jsoup.nodes.Node childNode : document.childNodes()) {
            if (childNode instanceof TextNode) {
                TextNode textNode = (TextNode) childNode;
                String text = textNode.text();
                if (StringUtil.isBlank(text)) {
                    continue;
                }
                com.vladsch.flexmark.util.ast.Document parseDocument = parser.parse(text);
                if (hasMarkdownNodes(parseDocument)) {
                    NodeVisitor visitor = new NodeVisitor(
                            new VisitHandler<>(Image.class, imageNode -> {
                                // 获取原始图片 URL
                                String originalUrl = imageNode.getUrl().toString();
                                // 替换路径（仅替换包含旧前缀的路径）
                                if (pngUrlMap.containsKey(originalUrl)) {
                                    String newPath = pngUrlMap.get(originalUrl);
                                    imageNode.setUrl(BasedSequence.of(newPath));
                                    //imageNode.setText(BasedSequence.of(newPath));
                                }
                            }
                            )
                    );
                    // 步骤3：执行遍历（触发 URL 修改）
                    visitor.visit(parseDocument);
                    String childHtml = renderer.render(parseDocument);
                    Element paragraph1 = Jsoup.parseBodyFragment(childHtml).body().child(0);
                    textNode.replaceWith(paragraph1);
                }
            } else {
                converHtml(childNode, pngUrlMap);
            }
        }
    }


    /**
     * 递归检查节点树中是否包含 Markdown 特定节点
     */
    private static boolean hasMarkdownNodes(Node node) {
        // 检查当前节点是否是 Markdown 特定节点
        if (MARKDOWN_NODES.contains(node.getClass())) {
            return true;
        }

        // 检查子节点
        ReversiblePeekingIterator<Node> children = node.getChildren().iterator();
        while (children.hasNext()) {
            Node child = children.next();
            System.out.println(child.getClass());
            if (hasMarkdownNodes(child)) {
                return true;
            }
        }

        return false;
    }

    public static void main(String[] args) {
        try {
            String content = new String(Files.readAllBytes(Paths.get("C:\\Users\\gengz\\Downloads\\Z8WhdqWFwo79xRxkWQgcGvucncc(1).md")), StandardCharsets.UTF_8);
            Map<String, String> urlMap = new HashMap<>();
            urlMap.put("static/Bx5KbKf7EoRLyVxSXvqccRpSngh.png", "https://cmm-custom.prnasia.com/cms-test/attachment/20250901151435953/MBoXbeqMJozerux81HXcJMMgnpd.png");
            urlMap.put("static/MBoXbeqMJozerux81HXcJMMgnpd.png", "https://cmm-custom.prnasia.com/cms-test/attachment/20250901151435953/MBoXbeqMJozerux81HXcJMMgnpd.png");
            urlMap.put("static/E5CHb5KROoDRHOxm7Yici8M3nAb.png", "https://cmm-custom.prnasia.com/cms-test/attachment/20250901151435953/MBoXbeqMJozerux81HXcJMMgnpd.png");
            String string = modifyImageUrlsAndHtmlContent(content, urlMap);
            System.out.println("结束");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
